home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Online / SpeakFreely / src / libdes / enc_read.c < prev    next >
C/C++ Source or Header  |  2000-05-18  |  6KB  |  190 lines

  1. /* lib/des/enc_read.c */
  2. /* Copyright (C) 1995 Eric Young (eay@mincom.oz.au)
  3.  * All rights reserved.
  4.  * 
  5.  * This file is part of an SSL implementation written
  6.  * by Eric Young (eay@mincom.oz.au).
  7.  * The implementation was written so as to conform with Netscapes SSL
  8.  * specification.  This library and applications are
  9.  * FREE FOR COMMERCIAL AND NON-COMMERCIAL USE
  10.  * as long as the following conditions are aheared to.
  11.  * 
  12.  * Copyright remains Eric Young's, and as such any Copyright notices in
  13.  * the code are not to be removed.  If this code is used in a product,
  14.  * Eric Young should be given attribution as the author of the parts used.
  15.  * This can be in the form of a textual message at program startup or
  16.  * in documentation (online or textual) provided with the package.
  17.  * 
  18.  * Redistribution and use in source and binary forms, with or without
  19.  * modification, are permitted provided that the following conditions
  20.  * are met:
  21.  * 1. Redistributions of source code must retain the copyright
  22.  *    notice, this list of conditions and the following disclaimer.
  23.  * 2. Redistributions in binary form must reproduce the above copyright
  24.  *    notice, this list of conditions and the following disclaimer in the
  25.  *    documentation and/or other materials provided with the distribution.
  26.  * 3. All advertising materials mentioning features or use of this software
  27.  *    must display the following acknowledgement:
  28.  *    This product includes software developed by Eric Young (eay@mincom.oz.au)
  29.  * 
  30.  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  31.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  32.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  33.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  34.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  35.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  36.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  37.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  38.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  39.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  40.  * SUCH DAMAGE.
  41.  * 
  42.  * The licence and distribution terms for any publically available version or
  43.  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  44.  * copied and put under another distribution licence
  45.  * [including the GNU Public Licence.]
  46.  */
  47.  
  48. #include <stdio.h>
  49. #include <errno.h>
  50. #include "des_locl.h"
  51.  
  52. /* This has some uglies in it but it works - even over sockets. */
  53. extern int errno;
  54. int des_rw_mode=DES_PCBC_MODE;
  55.  
  56. int des_enc_read(fd, buf, len, sched, iv)
  57. int fd;
  58. char *buf;
  59. int len;
  60. des_key_schedule sched;
  61. des_cblock (*iv);
  62.     {
  63.     /* data to be unencrypted */
  64.     int net_num=0;
  65.     unsigned char net[BSIZE];
  66.     /* extra unencrypted data 
  67.      * for when a block of 100 comes in but is des_read one byte at
  68.      * a time. */
  69.     static char unnet[BSIZE];
  70.     static int unnet_start=0;
  71.     static int unnet_left=0;
  72.     int i;
  73.     long num=0,rnum;
  74.     unsigned char *p;
  75.  
  76.     /* left over data from last decrypt */
  77.     if (unnet_left != 0)
  78.         {
  79.         if (unnet_left < len)
  80.             {
  81.             /* we still still need more data but will return
  82.              * with the number of bytes we have - should always
  83.              * check the return value */
  84.             memcpy(buf,&(unnet[unnet_start]),
  85.                 (unsigned int)unnet_left);
  86.             /* eay 26/08/92 I had the next 2 lines
  87.              * reversed :-( */
  88.             i=unnet_left;
  89.             unnet_start=unnet_left=0;
  90.             }
  91.         else
  92.             {
  93.             memcpy(buf,&(unnet[unnet_start]),(unsigned int)len);
  94.             unnet_start+=len;
  95.             unnet_left-=len;
  96.             i=len;
  97.             }
  98.         return(i);
  99.         }
  100.  
  101.     /* We need to get more data. */
  102.     if (len > MAXWRITE) len=MAXWRITE;
  103.  
  104.     /* first - get the length */
  105.     net_num=0;
  106.     while (net_num < HDRSIZE) 
  107.         {
  108.         i=read(fd,&(net[net_num]),(unsigned int)HDRSIZE-net_num);
  109.         if ((i == -1) && (errno == EINTR)) continue;
  110.         if (i <= 0) return(0);
  111.         net_num+=i;
  112.         }
  113.  
  114.     /* we now have at net_num bytes in net */
  115.     p=net;
  116.     num=0;
  117.     n2l(p,num);
  118.     /* num should be rounded up to the next group of eight
  119.      * we make sure that we have read a multiple of 8 bytes from the net.
  120.      */
  121.     if ((num > MAXWRITE) || (num < 0)) /* error */
  122.         return(-1);
  123.     rnum=(num < 8)?8:((num+7)/8*8);
  124.  
  125.     net_num=0;
  126.     while (net_num < rnum)
  127.         {
  128.         i=read(fd,&(net[net_num]),(unsigned int)rnum-net_num);
  129.         if ((i == -1) && (errno == EINTR)) continue;
  130.         if (i <= 0) return(0);
  131.         net_num+=i;
  132.         }
  133.  
  134.     /* Check if there will be data left over. */
  135.     if (len < num)
  136.         {
  137.         if (des_rw_mode & DES_PCBC_MODE)
  138.             pcbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
  139.                 num,sched,iv,DES_DECRYPT);
  140.         else
  141.             cbc_encrypt((des_cblock *)net,(des_cblock *)unnet,
  142.                 num,sched,iv,DES_DECRYPT);
  143.         memcpy(buf,unnet,(unsigned int)len);
  144.         unnet_start=len;
  145.         unnet_left=num-len;
  146.  
  147.         /* The following line is done because we return num
  148.          * as the number of bytes read. */
  149.         num=len;
  150.         }
  151.     else
  152.         {
  153.         /* >output is a multiple of 8 byes, if len < rnum
  154.          * >we must be careful.  The user must be aware that this
  155.          * >routine will write more bytes than he asked for.
  156.          * >The length of the buffer must be correct.
  157.          * FIXED - Should be ok now 18-9-90 - eay */
  158.         if (len < rnum)
  159.             {
  160.             char tmpbuf[BSIZE];
  161.  
  162.             if (des_rw_mode & DES_PCBC_MODE)
  163.                 pcbc_encrypt((des_cblock *)net,
  164.                     (des_cblock *)tmpbuf,
  165.                     num,sched,iv,DES_DECRYPT);
  166.             else
  167.                 cbc_encrypt((des_cblock *)net,
  168.                     (des_cblock *)tmpbuf,
  169.                     num,sched,iv,DES_DECRYPT);
  170.  
  171.             /* eay 26/08/92 fix a bug that returned more
  172.              * bytes than you asked for (returned len bytes :-( */
  173.             memcpy(buf,tmpbuf,(unsigned int)num);
  174.             }
  175.         else
  176.             {
  177.             if (des_rw_mode & DES_PCBC_MODE)
  178.                 pcbc_encrypt((des_cblock *)net,
  179.                     (des_cblock *)buf,num,sched,iv,
  180.                     DES_DECRYPT);
  181.             else
  182.                 cbc_encrypt((des_cblock *)net,
  183.                     (des_cblock *)buf,num,sched,iv,
  184.                     DES_DECRYPT);
  185.             }
  186.         }
  187.     return(num);
  188.     }
  189.  
  190.